package org.example.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.example.mapper.UserInfoMapper;
import org.example.model.common.AppHttpCodeEnum;
import org.example.model.common.PageResponseDto;
import org.example.model.common.ResponseResult;
import org.example.model.user.dtos.LoginDto;
import org.example.model.user.dtos.UserIdentityDto;
import org.example.model.user.dtos.UserInfoNoPwdDto;
import org.example.model.user.entities.UserInfo;
import org.example.model.user.enums.UserSex;
import org.example.model.user.enums.UserStatus;
import org.example.model.user.vos.AddUserInfoVo;
import org.example.model.user.vos.LoginVo;
import org.example.model.user.vos.SearchUserInfoVo;
import org.example.service.user.UserInfoService;
import org.example.utils.JwtUtils;
import org.example.utils.MD5Utils;
import org.example.utils.UserIdThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户信息服务层实现
 */
@Service
@Transactional
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 添加一条用户信息
     */
    @Override
    public ResponseResult<Boolean> InsertUserInfo(AddUserInfoVo addUserInfoVo) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (addUserInfoVo == null) {
            // 缺少参数
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(addUserInfoVo, userInfo);
        userInfo.setPassword(MD5Utils.encode(userInfo.getPassword()));
        this.HandleUserInfoBasic(userInfo);
        Boolean flag = userInfoMapper.insert(userInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    //处理添加用户信息时共有信息的处理
    private void HandleUserInfoBasic (UserInfo userInfo) {
        // 获取进程中的用户数据
        UserIdentityDto userIdentityDto = UserIdThreadLocalUtils.getUser();
        if (userInfo.getId() == 0) {
            userInfo.setCreateUserId(userIdentityDto.getId());
            userInfo.setCreateTime(LocalDateTime.now());
            userInfo.setIsDeleted(false);
        }
        userInfo.setUpdateUserId(userIdentityDto.getId());
        userInfo.setUpdateTime(LocalDateTime.now());
    }

    /**
     * 根据id修改一条用户信息
     */
    @Override
    public ResponseResult<Boolean> UpdateUserInfoById(AddUserInfoVo addUserInfoVo) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (addUserInfoVo == null || addUserInfoVo.getId() <= 0) {
            // 缺少参数
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        UserInfo userInfo = userInfoMapper.selectById(addUserInfoVo.getId());
        // 密码字段数据不为空，加密处理
        if (StringUtils.isNotBlank(addUserInfoVo.getPassword())) {
            addUserInfoVo.setPassword(MD5Utils.encode(addUserInfoVo.getPassword()));
        }
        BeanUtils.copyProperties(addUserInfoVo, userInfo);
        this.HandleUserInfoBasic(userInfo);
        Boolean flag = userInfoMapper.updateById(userInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 分页根据条件（用户名，手机号模糊查询，性别，部门，职位，状态精确查询）获取用户信息列表
     */
    @Override
    public ResponseResult<PageResponseDto<List<UserInfoNoPwdDto>>> SelectUserInfoByConditions(SearchUserInfoVo searchUserInfoVo) {
        ResponseResult<PageResponseDto<List<UserInfoNoPwdDto>>> result = new ResponseResult<>();
        // 参数审查
        if (searchUserInfoVo == null) {
            // 缺少参数 查询条件
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        // 查询条件
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getIsDeleted, false);
        // 创建时间倒排
        queryWrapper.orderByDesc(UserInfo::getCreateTime);
        // 用户名，手机号模糊查询，性别，部门，职位，状态精确查询
        queryWrapper.like(StringUtils.isNotBlank(searchUserInfoVo.getUsername()), UserInfo::getUsername, searchUserInfoVo.getUsername())
                .like(StringUtils.isNotBlank(searchUserInfoVo.getPhone()), UserInfo::getPhone, searchUserInfoVo.getPhone())
                .eq(searchUserInfoVo.getSex() != null, UserInfo::getSex, searchUserInfoVo.getSex())
                .eq(searchUserInfoVo.getStatus() != null, UserInfo::getStatus, searchUserInfoVo.getStatus())
                .eq(searchUserInfoVo.getOrganizationId() != null, UserInfo::getOrganizationId, searchUserInfoVo.getOrganizationId())
                .eq(searchUserInfoVo.getPositionId() != null, UserInfo::getPositionId, searchUserInfoVo.getPositionId());
        // 分页处理数据
        IPage<UserInfo> page = new Page<>(searchUserInfoVo.getPageIndex(),searchUserInfoVo.getPageSize());
        IPage<UserInfo> userListByPage = userInfoMapper.selectPage(page, queryWrapper);
        // 应返回数据
        PageResponseDto<List<UserInfoNoPwdDto>> pageResponseDto = new PageResponseDto<>();
        pageResponseDto.setSize(userInfoMapper.selectCount(queryWrapper).intValue());
        List<UserInfo> userInfoRecords = userListByPage.getRecords();
        List<UserInfoNoPwdDto> userInfoNoPwdDtos = new ArrayList<>();
        UserInfoNoPwdDto userInfoNoPwdDto = null;
        for (UserInfo userInfoRecord : userInfoRecords) {
            userInfoNoPwdDto = new UserInfoNoPwdDto();
            BeanUtils.copyProperties(userInfoRecord,userInfoNoPwdDto);
            userInfoNoPwdDtos.add(userInfoNoPwdDto);
        }
        pageResponseDto.setData(userInfoNoPwdDtos);
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), pageResponseDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 根据id删除一条用户信息
     */
    @Override
    public ResponseResult<Boolean> DeleteUserInfoById(int id) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (id <= 0) {
            // 缺少参数 日报所属人id
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        UserInfo userInfo = userInfoMapper.selectById(id);
        userInfo.setIsDeleted(true);
        this.HandleUserInfoBasic(userInfo);
        Boolean flag = userInfoMapper.updateById(userInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 用户登录
     */
    @Override
    public ResponseResult<LoginDto> Login(LoginVo loginVo) {
        ResponseResult<LoginDto> result = new ResponseResult<>();
        LoginDto loginDto = new LoginDto();
        loginDto.setIsSuccess(false);
        if (loginVo == null) {
            // 缺少登录认证参数
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        // 检测登录账号或密码是否为空
        if (loginVo.getPhone() == null || loginVo.getPassword() == null) {
            loginDto.setMessage("登录账号或密码不能为空");
            result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
            return result;
        }
        // 检测当前的账户在数据库是否存在
        LambdaQueryWrapper<UserInfo> loginQuery = new LambdaQueryWrapper<>();
        loginQuery.eq(UserInfo::getIsDeleted, false)
                .eq(UserInfo::getPhone, loginVo.getPhone());
        List<UserInfo> userInfoList = userInfoMapper.selectList(loginQuery);
        if (userInfoList == null || userInfoList.size() == 0) {
            loginDto.setMessage("该用户不存在");
            result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
            return result;
        }
        for (UserInfo userInfo : userInfoList) {
            if (userInfo.getStatus() == UserStatus.Disable.ordinal()) {
                loginDto.setMessage("该用户账号已禁用");
                result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
                return result;
            }
            if (userInfo.getPassword().equals(MD5Utils.encode(loginVo.getPassword()))) {
                loginDto.setAccessToken(JwtUtils.GenerateToken(userInfo));
                loginDto.setIsSuccess(true);
                loginDto.setMessage("登录成功");
                result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
                return result;
            }
        }
        loginDto.setMessage("密码错误");
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 用户注册
     */
    @Override
    public ResponseResult<LoginDto> Register(LoginVo loginVo) {
        ResponseResult<LoginDto> result = new ResponseResult<>();
        LoginDto loginDto = new LoginDto();
        loginDto.setIsSuccess(false);
        if (loginVo == null) {
            // 缺少注册认证参数
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        // 检测登录账号或密码是否为空
        if (loginVo.getPhone() == null || loginVo.getPassword() == null) {
            loginDto.setMessage("登录账号或密码不能为空");
            result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
            return result;
        }
        // 检测当前的账户在数据库是否存在
        LambdaQueryWrapper<UserInfo> loginQuery = new LambdaQueryWrapper<>();
        loginQuery.eq(UserInfo::getIsDeleted, false)
                .eq(UserInfo::getPhone, loginVo.getPhone());
        List<UserInfo> userInfoList = userInfoMapper.selectList(loginQuery);
        if (userInfoList == null || userInfoList.size() == 0) {
            // 添加用户
            this.handleRegisterUser(loginVo, loginDto, result);
            return result;
        }
        Boolean flag = false;
        for (UserInfo userInfo : userInfoList) {
            if (userInfo.getPassword().equals(MD5Utils.encode(loginVo.getPassword()))) flag = true;
        }
        if (!flag) {
            // 添加用户
            this.handleRegisterUser(loginVo, loginDto, result);
            return result;
        }
        loginDto.setMessage("该用户已存在");
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 注册时添加新用户统一操作
     */
    private void handleRegisterUser (LoginVo loginVo, LoginDto loginDto, ResponseResult<LoginDto> result) {
        AddUserInfoVo addUserInfoVo = new AddUserInfoVo();
        BeanUtils.copyProperties(loginVo, addUserInfoVo);
        addUserInfoVo.setUsername("User");
        addUserInfoVo.setSex(UserSex.Man.ordinal());
        addUserInfoVo.setStatus(UserStatus.Enable.ordinal());
        ResponseResult<Boolean> insertUserInfo = this.InsertUserInfo(addUserInfoVo);
        loginDto.setIsSuccess(insertUserInfo.getData());
        loginDto.setMessage("注册成功");
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), loginDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
    }
}

